package com.jia.service.impl;

import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jia.common.exception.MyException;
import com.jia.entity.SysRole;
import com.jia.entity.SysUser;
import com.jia.entity.SysUserInfo;
import com.jia.entity.SysUserRole;
import com.jia.entity.netty.ShutDownMsg;
import com.jia.entity.vo.LoginVo;
import com.jia.mapper.SysRoleMapper;
import com.jia.mapper.SysUserInfoMapper;
import com.jia.mapper.SysUserMapper;
import com.jia.mapper.SysUserRoleMapper;
import com.jia.service.SysUserRoleService;
import com.jia.service.SysUserService;
import com.jia.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 杜佳佳
 * @since 2021-05-23
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private SysUserInfoMapper sysUserInfoMapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;


    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public SysUser getByUsername(String username) {
        SysUser sysUser = baseMapper.selectOne(new QueryWrapper<SysUser>().eq("username", username));
        SysUserInfo userInfo = sysUserInfoMapper.selectOne(new QueryWrapper<SysUserInfo>().eq("user_id", sysUser.getId()));
        sysUser.setUserInfo(userInfo);
        return sysUser;
    }

    @Override
    public String getUserAuthorityInfo(String userId) {

        String authority = "";
        // 获取角色操作权限
        List<SysRole> roles = sysUserRoleService.getRoleListByUserId(userId);
        if (roles.size() > 0) {
            String roleCodes = roles.stream().map(r -> "ROLE_" + r.getCode()).collect(Collectors.joining(","));
            authority = roleCodes;
        }

        return authority;
    }

    @Override
    public Map<String, Object> getInfoByToken(HttpServletRequest request) {

        Map<String, Object> map = new HashMap<>();
        String token = request.getHeader("Authorization");
        Claims claims = jwtUtils.parseToken(token);
        String username = claims.getSubject();
        SysUser sysUser = this.getByUsername(username);
        map.put("username",username);
        map.put("avatar",sysUser.getAvatar());
        map.put("nickname",sysUser.getNickname());
        SysUserInfo sysUserInfo = sysUserInfoMapper.selectOne(new QueryWrapper<SysUserInfo>().eq("user_id", sysUser.getId()));
        map.put("userInfo",sysUserInfo);

        String roleStr = this.getUserAuthorityInfo(sysUser.getId());
        ArrayList<String> roles =
                new ArrayList<String>(Arrays.asList(roleStr.split(",")));
        map.put("roles",roles);

        return map;
    }

    @Transactional
    @Override
    public void register(SysUser sysUser) {

        String username = sysUser.getUsername();
        String password = sysUser.getPassword();
        String nickname = sysUser.getNickname();

        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password) || StringUtils.isEmpty(nickname) ){
            throw new MyException("注册信息不能为空",400);
        }
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        Integer count = baseMapper.selectCount(wrapper);
        if(count >0){
            throw new MyException("该手机已经注册",400);
        }
        // 添加用户表
        String encode = passwordEncoder.encode(password);
        sysUser.setPassword(encode);
        baseMapper.insert(sysUser);
        // 添加用户信息表
        SysUserInfo sysUserInfo = new SysUserInfo();
        sysUserInfo.setUserId(sysUser.getId());
        sysUserInfoMapper.insert(sysUserInfo);
        // 添加用户角色表
        SysRole sysRole = sysRoleMapper.selectOne(new QueryWrapper<SysRole>().eq("code", "normal"));
        String roleId = sysRole.getId();
        SysUserRole sysUserRole = new SysUserRole();
        sysUserRole.setRoleId(roleId);
        sysUserRole.setUserId(sysUser.getId());
        sysUserRoleMapper.insert(sysUserRole);

    }

    @Override
    public void changePassword(SysUser sysUser) {
        String username = sysUser.getUsername();
        String password = sysUser.getPassword();
        String encode = passwordEncoder.encode(password);

        SysUser user = baseMapper.selectOne(new QueryWrapper<SysUser>().eq("username", username));
        if(user == null){
            throw new MyException("您不是我们的用户",400);
        }
        user.setPassword(encode);
        baseMapper.updateById(user);
    }

    @Override
    public Map<String, Object> getInfo(LoginVo loginVo) {
        Map<String, Object> map = new HashMap<>();

        String username = loginVo.getUsername();
        String did = loginVo.getDid();
        SysUser sysUser = this.getByUsername(username);
        map.put("username",username);
        map.put("avatar",sysUser.getAvatar());
        map.put("nickname",sysUser.getNickname());
        SysUserInfo sysUserInfo = sysUserInfoMapper.selectOne(new QueryWrapper<SysUserInfo>().eq("user_id", sysUser.getId()));
        map.put("userInfo",sysUserInfo);

        String roleStr = this.getUserAuthorityInfo(sysUser.getId());
        ArrayList<String> roles =
                new ArrayList<String>(Arrays.asList(roleStr.split(",")));
        map.put("roles",roles);

        // 登录成功后保存用户id和设备id
        String redisDid = redisTemplate.opsForValue().get(sysUser.getId());
        if (redisDid != null && !did.equals(redisDid)){
            System.out.println("重新登录了...");
            ShutDownMsg shutDownMsg = new ShutDownMsg();
            shutDownMsg.setDid(redisDid);
            rabbitTemplate.convertAndSend("ws_exchange","",shutDownMsg);
        }

        redisTemplate.opsForValue().set(sysUser.getId(),did);


        return map;
    }
}
